package com.broada.apm.dao.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import com.broada.apm.dao.ServiceDao;
import com.broada.apm.model.SSLCertificate;
import com.broada.apm.model.Service;

public class MysqlServiceDao extends MysqlAbstractDao implements ServiceDao {

	public static final String SERVICE_NAMESPACE = "com.broada.apm.dao.ServiceDao.";
	
	@Override
	public void addService(Service service) {
		getSqlSession().insert(SERVICE_NAMESPACE + "addService", service);
		if(service.getNodeIds() != null && service.getNodeIds().length > 0)
			getSqlSession().insert(SERVICE_NAMESPACE + "addClusterServiceMap", service);
		Set<String> ips = new HashSet<String>();
		if (service.getFilterIps() != null && service.getFilterIps().length > 0) {
			for (String ip : service.getFilterIps()) {
				if (StringUtils.isNotBlank(ip)) {
					ips.add(ip);
				}
			}
		}
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteFilterIpsMap", service.getId());
		if (!ips.isEmpty()) {
			service.setFilterIps(ips.toArray(new String[ips.size()]));
			getSqlSession().insert(SERVICE_NAMESPACE + "addFilterIpsMap", service);
		}
	}

	@Override
	@Transactional
	public void updateService(Service service) {
		if(service.getName() == null) {
			Service ser = getServiceById(service.getId());
			service.setName(ser.getName());
		}
		getSqlSession().update(SERVICE_NAMESPACE + "updateService", service);
		if(service.getNodeIds() != null && service.getNodeIds().length > 0) {
			getSqlSession().delete(SERVICE_NAMESPACE + "deleteClusterMap", service.getId());
			getSqlSession().insert(SERVICE_NAMESPACE + "addClusterServiceMap", service);
		}
		if(service.getNodeType() == 1) {//如果是普通，可能是脱离集群，需删除集群关联关系
			getSqlSession().delete(SERVICE_NAMESPACE + "deleteClusterMap", service.getId());
		}
		// 删除或保存节点中发送的节点和接收的节点
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteFilterIpsMap", service.getId());
		Set<String> ips = new HashSet<String>();
		if (service.getFilterIps() != null && service.getFilterIps().length > 0) {
			for (String ip : service.getFilterIps()) {
				if (StringUtils.isNotBlank(ip)) {
					ips.add(ip);
				}
			}
		}
		if (!ips.isEmpty()) {
			service.setFilterIps(ips.toArray(new String[ips.size()]));
			getSqlSession().insert(SERVICE_NAMESPACE + "addFilterIpsMap", service);
		}
	}

	@Override
	@Transactional
	public void deleteService(Service service) {
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteClusterMap", service.getId());
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteFilterIpsMap", service.getId());
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteSSLCertificate", service.getId());
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteService", service);
	}

	@Override
	public Service getServiceById(String serviceId) {
		Service service = getSqlSession().selectOne(SERVICE_NAMESPACE + "getServiceById", serviceId);
		if(service!= null) {
			if (service.getNodeType() == Service.NodeTypeCluster) {
				List<String> nodeIds = getSqlSession().selectList(SERVICE_NAMESPACE + "getChildServiceId", service.getId());
				service.setNodeIds(nodeIds.toArray(new String[]{}));
			}
			
			List<String> sendNodeIds = getSqlSession().selectList(SERVICE_NAMESPACE + "getIpsByServiceId", service.getId());
			if (!sendNodeIds.isEmpty()) {
				service.setFilterIps(sendNodeIds.toArray(new String[]{}));
			}
		}
		return service;
	}

	@Override
	public List<Service> getServicesByAppId(String appId) {
		List<Service> services = getSqlSession().selectList(SERVICE_NAMESPACE + "getServicesByAppId", appId);
		for(Service service : services) {
			if(service.getNodeType() == 2) {
				List<String> nodeIds = getSqlSession().selectList(SERVICE_NAMESPACE + "getChildServiceId", service.getId());
				service.setNodeIds(nodeIds.toArray(new String[]{}));
			}
			List<String> sendNodeIds = getSqlSession().selectList(SERVICE_NAMESPACE + "getIpsByServiceId", service.getId());
			if (!sendNodeIds.isEmpty()) {
				service.setFilterIps(sendNodeIds.toArray(new String[]{}));
			}
		}
		return services;
	}

	@Override
	public void deleteServiceByAppId(String appId) {
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteServiceByAppId", appId);
		// 删除该应用系统下所有的IP过滤关系
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteFilterIpsMapByAppId", appId);
	}

	@Override
	public List<Service> getChildServiceByClusterId(String clusterId) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getChildServiceByClusterId", clusterId);
	}

	@Override
	public List<Service> getDisServiceByIpAndPort(Service service) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByIpAndPort", service);
	}

	@Override
	public Service getDisServiceById(String serviceId) {
		return getSqlSession().selectOne(SERVICE_NAMESPACE + "getDisServiceById", serviceId);
	}

	@Override
	public void updateDisService(Service service) {
		getSqlSession().update(SERVICE_NAMESPACE + "updateDisService", service);
	}

	@Override
	public List<Service> getDisServiceByIpNum(long ipNum) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByIpNum", ipNum);
	}

	@Override
	public List<Service> getDisServiceByProtocal(Service service, String orderBy, boolean desc) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		if ("ipNum".equals(orderBy)) {
			orderBy = "ip_num";
		}
		if ("createdAt".equals(orderBy)) {
			orderBy = "create_at";
		}
		if ("autoDiscoveryProtocol".equals(orderBy)) {
			orderBy = "auto_discovery_protocol";
		}
		if ("createBy".equals(orderBy)) {
			orderBy = "create_by";
		}
 		map.put("orderBy", orderBy);
		map.put("desc", desc);
		map.put("service", service);
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByProtocal", map);
	}

	@Override
	public void addDisService(Service service) {
		getSqlSession().insert(SERVICE_NAMESPACE + "addDisService", service);
	}

	@Override
	public List<Service> getAllServicesNotCluster() {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getAllServicesNotCluster");
	}

	@Override
	public SSLCertificate getSSLByServiceId(String serviceId) {
		SSLCertificate sslCertificate = getSqlSession().selectOne(SERVICE_NAMESPACE + "getSSLByServiceId", serviceId);
		return sslCertificate;
	}

	@Override
	public void addSSLCertificate(SSLCertificate sslCertificate) {
		getSqlSession().insert(SERVICE_NAMESPACE + "addSSLCertifivate", sslCertificate);
	}

	@Override
	public void updateSSLCertificate(SSLCertificate sslCertificate) {
		getSqlSession().update(SERVICE_NAMESPACE + "updateSSLCertificate", sslCertificate);
		
	}

	@Override
	public void deleteSSLCertificate(SSLCertificate sslCertificate) {
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteSSLCertificate", sslCertificate.getServiceId());
		
	}

	@Override
	public List<Service> getDisServiceByKeyWord(Service service, String keyWord, String orderBy, boolean desc) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		if ("ipNum".equals(orderBy)) {
			orderBy = "ip_num";
		}
		if ("createdAt".equals(orderBy)) {
			orderBy = "create_at";
		}
		if ("autoDiscoveryProtocol".equals(orderBy)) {
			orderBy = "auto_discovery_protocol";
		}
		if ("createBy".equals(orderBy)) {
			orderBy = "create_by";
		}
 		map.put("orderBy", orderBy);
		map.put("desc", desc);
		map.put("service", service);
		map.put("keyWord", keyWord);
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByKeyWord", map);
	}

	@Override
	public List<Service> getDisServiceByCondition(Service service, String orderBy, boolean desc) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		if ("ipNum".equals(orderBy)) {
			orderBy = "ip_num";
		}
		if ("createdAt".equals(orderBy)) {
			orderBy = "create_at";
		}
		if ("autoDiscoveryProtocol".equals(orderBy)) {
			orderBy = "auto_discovery_protocol";
		}
		if ("createBy".equals(orderBy)) {
			orderBy = "create_by";
		}
 		map.put("orderBy", orderBy);
		map.put("desc", desc);
		map.put("service", service);
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByCondition", map);
	}

	@Override
	public void deleteDiscoveryService(Service service) {
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteDiscoveryService", service);
		
	}

	@Override
	public List<Service> getTopoServiceBySerivceId(String id) {
		String serviceId = "-" + id;
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getAppServiceByServiceId", serviceId);
	}

	@Override
	public Service getAppServiceByIpAndPort(Service service) {
		return getSqlSession().selectOne(SERVICE_NAMESPACE + "getAppServiceByIpAndPort", service);
	}

	@Override
	public List<Service> getDisServiceFocusOrNot(Service service, String serviceType, String orderByMysql, boolean desc, int pageSize, int pageIndex, int severity, Date startDate, Date endDate) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(serviceType)) {
			map.put("serviceType", serviceType);
		}
		map.put("service", service);
		if (StringUtils.isNotBlank(orderByMysql) && "protocolName".equals(orderByMysql)) {
			orderByMysql = "protocol, auto_discovery_protocol";
		}
		if (StringUtils.isBlank(orderByMysql)) {
			orderByMysql = "ip";
		}
		map.put("orderByMysql", orderByMysql);
		map.put("desc", desc);
		map.put("pageSize", pageSize);
		map.put("pageIndex", pageIndex * pageSize);
		map.put("severity", severity);
//		map.put("startTime", startDate);
//		map.put("endTime", endDate);
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceFocusOrNot", map);
	}

	@Override
	public int getServiceCount(int focus) {
		if (focus == 1) {
			return getSqlSession().selectOne(SERVICE_NAMESPACE + "getServiceFocusCount", focus);
		} else {
			return getSqlSession().selectOne(SERVICE_NAMESPACE + "getServiceCount", focus);
		}
	}

	@Override
	public void updateDisServiceFocus(Service service) {
		getSqlSession().update(SERVICE_NAMESPACE + "updateDisServiceFocus", service);
	}

	@Override
	public List<Service> getDisServiceByLabelName(String ip) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getDisServiceByLabelName", ip);
	}

	@Override
	public void updateDisServiceLua(Service service) {
		getSqlSession().update(SERVICE_NAMESPACE + "updateDisServiceLua", service);
	}

	@Override
	public List<String> getIpsByServiceId(String dstId) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getIpsByServiceId", dstId);
	}

	@Override
	public List<String> getIpsByAppId(String appId) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getIpsByAppId", appId);
	}
	
	@Override
	public void updateServiceLikeDisId(Service service) {
		getSqlSession().update(SERVICE_NAMESPACE + "updateServiceLikeDisId", service);
	}
	
	@Override
	public List<Service> getAllDisService() {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getAllDisService");
	}

	@Override
	public void updateServiceName(Service service) {
		if(service.getName() == null) {
			Service ser = getServiceById(service.getId());
			service.setName(ser.getName());
		}
		getSqlSession().update(SERVICE_NAMESPACE + "updateService", service);
	}

	@Override
	public String getClusterServiceByChildId(String serviceId) {
		return getSqlSession().selectOne(SERVICE_NAMESPACE + "getClusterServiceByChildId", serviceId);
	}

	@Override
	public List<Service> getAllFocusedDisService() {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getAllFocusedDisService");
	}

	@Override
	public void deleteDiscoveryServiceByIds(List<String> serviceIds) {
		getSqlSession().delete(SERVICE_NAMESPACE + "deleteDiscoveryServiceByIds", serviceIds);
	}

	@Override
	public List<String> getChildrenServiceIds(String applicationId) {
		return getSqlSession().selectList(SERVICE_NAMESPACE + "getChildServiceId", applicationId);
	}
	
}
